using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;

namespace DrawToolsLib {
    /// <summary>
    /// Changing objects order: move to front/back.
    /// 
    /// Command keeps list of object IDs before and after operation.
    /// Using these lists, it is possible to undo/redo Move to ... operation.
    /// </summary>
    class CommandChangeOrder : CommandBase {
        // Object IDs before operation
        List<GraphicsBase> listBefore;

        // Object IDs after operation
        List<GraphicsBase> listAfter;


        // Create this command BEFORE operation.
        public CommandChangeOrder(DrawingCanvas drawingCanvas) {
            FillList(drawingCanvas, ref listBefore);
        }

        // Call this function AFTER operation.
        public void NewState(DrawingCanvas drawingCanvas) {
            FillList(drawingCanvas, ref listAfter);
        }

        /// <summary>
        /// Restore order to its state before change.
        /// </summary>
        public override void Undo(DrawingCanvas drawingCanvas) {
            ChangeOrder(drawingCanvas, listBefore);
        }

        /// <summary>
        /// Restore order to its state after change.
        /// </summary>
        public override void Redo(DrawingCanvas drawingCanvas) {
            ChangeOrder(drawingCanvas, listAfter);
        }

        // Fill list of Ids from graphics list
        private static void FillList(DrawingCanvas d, ref List<GraphicsBase> listToFill) {
            listToFill = new List<GraphicsBase>();

            foreach (GraphicsBase g in d.GraphicsList) {
                listToFill.Add(g);
            }
        }

        // Set selection order in graphicsList according to list of IDs
        private static void ChangeOrder(DrawingCanvas d, List<GraphicsBase> indexList) {

            // Read indexList, find every element in graphicsList by ID
            // and move it to tmpList.
            while (d.GraphicsList.Count > 0) {
                d.Pop(0);
            }

            // Now tmpList contains objects in correct order.
            // Read tmpList and add all its elements back to graphicsList.
            for (int i = 0; i < indexList.Count; i++ ) {
                d.Push(indexList[i]);
            }
        }


        /// <summary>
        /// Dump (for debugging)
        /// </summary>
        [Conditional("DEBUG")]
        static void Dump(List<int> list, string header) {
            Trace.WriteLine("");
            Trace.WriteLine(header);
            Trace.WriteLine("");

            string s = "";

            foreach (int n in list) {
                s += n.ToString(CultureInfo.InvariantCulture);
                s += " ";
            }

            Trace.WriteLine(s);
        }
    }
}
